package com.scalar.chiptrack.operations.dataentry.actions;

import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.db.DBXException;
import com.scalar.chiptrack.operations.dataentry.BOMLotBinData;
import com.scalar.chiptrack.operations.dataentry.LotDetails;
import com.scalar.chiptrack.operations.dataentry.dao.BOMDataEntryDAO;
import com.scalar.chiptrack.operations.dataentry.dao.DataEntryDAO;
import com.scalar.chiptrack.operations.dataentry.forms.BOMDataEntryForm;
import com.scalar.chiptrack.operations.dataentry.test.TestBinInfo;
import com.scalar.chiptrack.operations.process.Lot;
import com.scalar.chiptrack.operations.process.VendorLocation;
import com.scalar.chiptrack.operations.process.dao.BomPartEntryDAO;
import com.scalar.chiptrack.operations.process.dao.PartNumber;
import com.scalar.chiptrack.operations.vendor.dao.VendorDAO;
import com.scalar.chiptrack.users.Functionality;
import com.scalar.chiptrack.users.User;
import com.scalar.chiptrack.utils.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.LabelValueBean;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * Created by Sudhakar.
 * Date: May 12, 2005
 * Time: 10:59:32 AM
 */
public class BOMDataEntryAction extends ChipTrackAction
{
    //default constructor
    public BOMDataEntryAction()
    {
    }

    private static final String ACTION_NAME = "/bomDataEntry.do";

    public ActionForward execute( ActionMapping mapping,
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response ) throws Exception
    {

        HttpSession session = request.getSession();
        User user = ( User ) session.getAttribute( SessionKeys.USER_KEY );
        if ( user == null )
        {
            session.setAttribute( SessionKeys.SOURCE_PAGE_KEY, ACTION_NAME );
            return ( mapping.findForward( "login" ) );
        }
        else
        {
            if ( user.isActionAllowed ( Functionality.BOM_INVENTORY, User.USER_ACTION_MODIFY ) )
            {
                request.setAttribute ( "showMessage", "FALSE" );
            }
            else
            {
                request.setAttribute ( "showMessage", "TRUE" );
            }
        }
        HashMap errors                      = new LinkedHashMap();
        HashMap info                        = new LinkedHashMap();
        String action                       = request.getParameter( "action" );
        ArrayList partNumberList            = new ArrayList();
        ArrayList bomLocationList           = null;
        ArrayList locationList              = null;
        String actionForward 		        = "success";
        PartNumber partNumber 		        = null;
		VendorLocation vendorLocation 	    = null;
        BOMDataEntryForm bomDataEntryForm = ( BOMDataEntryForm ) form;

        if ( action == null || "null".equals( action ))
        {
            action = "";
            bomDataEntryForm.setLocationId( null);
            bomDataEntryForm.setLotId( null);
            bomDataEntryForm.setProcessStepId( null);
            bomDataEntryForm.setBomLotBinDataEntered( false);
            bomDataEntryForm.setBomLotBinData( new ArrayList() );
        }
        request.setAttribute ( "action", action );

        partNumberList = BomPartEntryDAO.loadAllBomPartNumbers( bomDataEntryForm.getProcessType(), "-1" );

        request.setAttribute( "partNumberSelectList", partNumberList );
        request.setAttribute( "processTypes", getProcessTypes() );
        LotDetails lotDetails = new LotDetails();
        request.setAttribute( "lotCategoryList", lotDetails.getLotCategoryType());
        request.setAttribute("lotStatusList", lotDetails.getLotStatusType());

        String locationId       = bomDataEntryForm.getLocationId ();
		String processStepId    = bomDataEntryForm.getProcessStepId ();
		String lotId            = bomDataEntryForm.getLotId ();


        if ( action.equals ( "location" ) || action.equals ( "save" ) || action.equals ( "lotnumber" ) || action.equals ( "partnumber" ) || "refresh".equalsIgnoreCase( action ))
		{
            bomLocationList = new ArrayList();
            try
            {
			    locationList = VendorDAO.getSelectedLocations ( Integer.parseInt ( processStepId ) );
            }
            catch(NumberFormatException nfe)
            {

            }
			for ( int i = 0; i < locationList.size(); i++ )
			{
				vendorLocation = ( VendorLocation ) locationList.get( i );
				bomLocationList.add ( new org.apache.struts.util.LabelValueBean ( vendorLocation.getLocationName (), vendorLocation.getLocationID () ) );
			}
			request.setAttribute ( "bomLocationList", bomLocationList );
		}
        if ( action.equals ( "location" ) || action.equals ( "lotnumber" ) || action.equals ( "save" ) || "refresh".equalsIgnoreCase( action ))
		{
        	ArrayList lotNumbersList = getLotList ( processStepId, locationId, bomDataEntryForm.getProcessType()  );
			request.setAttribute ( "lotNumbersList", lotNumbersList );
			if ( action.equals ( "location" ) )
			{
				bomDataEntryForm.setLotId("0");
			}
		}
        if ( action.equalsIgnoreCase( "lotnumber" ) )
        {
            if ( ( !"-1".equalsIgnoreCase( lotId ) ) )
            {
                LotDetails lot = null;
                if( Constants.LOCATION_TYPE_DIE_BANK.equalsIgnoreCase(bomDataEntryForm.getProcessType()) )
                {
                    //lot = LotDAO.getSortLotData ( lotId );
                    lot = DataEntryDAO.getInventoryLotInfo( lotId );
                    ArrayList binningDetailsList = DataEntryDAO.getDieBankBinLotInfo( lotId );
                    bomDataEntryForm.setBomLotBinData( binningDetailsList );
                }
                else if ( Constants.LOCATION_TYPE_FINISHED_GOODS.equalsIgnoreCase(bomDataEntryForm.getProcessType()) )
                {
                    lot = DataEntryDAO.getInventoryLotInfo( lotId );
                }
                bomDataEntryForm.setQtyIn("0".equals(lot.getDieQtyIn())?"":lot.getDieQtyIn());
                bomDataEntryForm.setQtyOut("0".equals(lot.getDieQtyOut())?"":lot.getDieQtyOut());
                bomDataEntryForm.setDateIn(lot.getDateIn());
                bomDataEntryForm.setDateOut(lot.getDateOut());
                bomDataEntryForm.setDateCode(lot.getDateCode());
                bomDataEntryForm.setComments(lot.getComments());
                bomDataEntryForm.setVendorLot(lot.getVendorLotNumber());
                bomDataEntryForm.setLotCategory( lot.getLotCategory() );
                bomDataEntryForm.setLotStatus( lot.getLotStatus() );
                bomDataEntryForm.setLotNumber( lot.getLotNumber() );
            }
            else
            {
                bomDataEntryForm.setQtyIn   ("");
                bomDataEntryForm.setQtyOut  ("");
                bomDataEntryForm.setDateIn  (StringUtils.formatDateToString(new java.sql.Date(System.currentTimeMillis()), "MM/dd/yyyy"));
                bomDataEntryForm.setDateOut ("");
                bomDataEntryForm.setDateCode("");
                bomDataEntryForm.setComments("");
                bomDataEntryForm.setVendorLot("");
                bomDataEntryForm.setBomLotBinData( new ArrayList() );
            }
            request.setAttribute ( "lotnumber", "true" );
        }
        if( action.equalsIgnoreCase("save"))
        {
            String quantityIn       = bomDataEntryForm.getQtyIn();
            String quantityOut      = bomDataEntryForm.getQtyOut();
            String dateIn           = bomDataEntryForm.getDateIn();
            String dateOut          = bomDataEntryForm.getDateOut();
            String vendorName       = bomDataEntryForm.getLocationName();
            String processType      = bomDataEntryForm.getProcessType();

            String lotCurrentStatus = "Running";
            /*if(dateOut != null && !("".equals(dateOut.trim())))
            {
                lotCurrentStatus = "Close";
            }*/
            //checking whether all the wafers are scrapped then closing the lot.
            /*boolean isClosed = getBinLotScrapStatus( bomDataEntryForm );
            if( isClosed == true )
            {
                lotCurrentStatus = "Close";
            }*/
            StringTokenizer st = new StringTokenizer ( vendorName, "/" );
            vendorName = st.nextToken();

            if ( dateIn.equals ( "" ) )
            {
                dateIn = null;
            }
            if ( dateOut.trim().equals ( "" ) )
            {
                dateOut = null;
            }

            ArrayList bomList       = new ArrayList();
            bomDataEntryForm.setQtyIn(quantityIn);
            bomDataEntryForm.setQtyOut(quantityOut);
            bomDataEntryForm.setDateIn(dateIn);
            bomDataEntryForm.setDateOut(dateOut);
            //bomDataEntryForm.setLotStatus( lotCurrentStatus);
            bomList.add(bomDataEntryForm);
            DBTransaction dbTransaction = null;
            boolean success = false;
            try
            {
                dbTransaction = DBTransaction.getInstance ();
                dbTransaction.begin ();
                //LotDAO.changeLotStatusToCloseByLotId( dbTransaction, lotId );
                if( Constants.LOCATION_TYPE_DIE_BANK.equalsIgnoreCase(bomDataEntryForm.getProcessType()) || Constants.LOCATION_TYPE_FINISHED_GOODS.equalsIgnoreCase(bomDataEntryForm.getProcessType()) )
                {
                    /*BOMDataEntryDAO.saveInventoryLot( dbTransaction, bomList.iterator(), processType, vendorName );
                    if (lotId.equals("-1"))
                    {
                        lotId = LotDAO.getLotId(dbTransaction, bomDataEntryForm.getLotNumber().trim(), locationId , processStepId); //get LotId in case of the new lot creation
                    }
                    int lotIdInt;
                    try
                    {
                        lotIdInt = Integer.parseInt( lotId);
                    }
                    catch( NumberFormatException e)
                    {
                        lotIdInt = -1;
                    }

                    if( bomDataEntryForm.getBomLotBinData() != null)
                    {
                        BOMDataEntryDAO.saveBinLotData(dbTransaction, bomDataEntryForm.getBomLotBinData(), lotIdInt);
                    }*/
                    //----
                    ArrayList invWipList = new ArrayList();
                    LotDetails invLotDetails = new LotDetails();
                    invLotDetails.setLotId(bomDataEntryForm.getLotId());
                    invLotDetails.setProcessType( bomDataEntryForm.getProcessType());
                    invLotDetails.setProcessStepId(bomDataEntryForm.getProcessStepId());
                    invLotDetails.setLocationId(bomDataEntryForm.getLocationId());
                    invLotDetails.setFabLotNumber( bomDataEntryForm.getLotNumber());
                    invLotDetails.setLotNumber( bomDataEntryForm.getLotNumber() );
                    invLotDetails.setVendorLotNumber( bomDataEntryForm.getLotNumber() );
                    invLotDetails.setDieQtyIn( bomDataEntryForm.getQtyIn() );
                    invLotDetails.setDieQtyOut( bomDataEntryForm.getQtyOut() );
                    invLotDetails.setDateIn( bomDataEntryForm.getDateIn() );
                    invLotDetails.setDateOut( bomDataEntryForm.getDateOut() );
                    invLotDetails.setVendorName( vendorName );
                    invLotDetails.setLotCategory( bomDataEntryForm.getLotCategory() );
                    invLotDetails.setDateCode( bomDataEntryForm.getDateCode() );
                    invLotDetails.setLotStatus( bomDataEntryForm.getLotStatus() );
                    invLotDetails.setComments( bomDataEntryForm.getComments() );
                    String waferIds = null;
                    if( bomDataEntryForm.getBomLotBinData() != null)
                    {
                        ArrayList binDataList = bomDataEntryForm.getBomLotBinData();
                        Iterator binLotDataIter = binDataList.iterator();
                        while (binLotDataIter.hasNext())
                        {
                            TestBinInfo bomLotBinData = (TestBinInfo) binLotDataIter.next();
                            waferIds = (waferIds==null ? bomLotBinData.getWaferId() : (waferIds+";"+bomLotBinData.getWaferId()) );
                        }
                        invLotDetails.setBinList( binDataList );
                    }

                    if (invLotDetails.getWaferQtyOut() != null && invLotDetails.getWaferQtyOut().trim().length() <= 0)
                    {
                        invLotDetails.setWaferQtyOut(null);
                    }
                    if (invLotDetails.getDateOut() != null && invLotDetails.getDateOut().trim().length() <= 0 )
                    {
                        invLotDetails.setDateOut(null);
                    }
                    if ( invLotDetails.getDieQtyOut() != null && invLotDetails.getDieQtyOut().trim().length() <= 0 )
                    {
                        invLotDetails.setDieQtyOut(null);
                    }
                    if (invLotDetails.getWaferQtyIn() != null && invLotDetails.getWaferQtyIn().trim().length() <= 0)
                    {
                        invLotDetails.setWaferQtyIn(null);
                    }
                    if ( invLotDetails.getDieQtyIn() != null && invLotDetails.getDieQtyIn().trim().length() <= 0 )
                    {
                        invLotDetails.setDieQtyIn(null);
                    }

                    invWipList.add( invLotDetails );

                    if( invWipList != null && invWipList.size() > 0 )
                    {
                        try
                        {
                            DataEntryDAO.saveDataEntryInventoryLot( dbTransaction, invWipList, user.getUserName() );
                            if ( invLotDetails.getBinList() != null && invLotDetails.getBinList().size() > 0 )
                            {
                                DataEntryDAO.saveDieBankBinInfo( dbTransaction, invLotDetails );
                            }
                            info.put ( "Lot Information Saved", null );
                        }
                        catch( Exception e )
                        {
                            e.printStackTrace();
                            errors.put( "Error storing the Inventory Lot information", null );
                        }
                    }
                    //----
                }
                /*else if ( Constants.LOCATION_TYPE_FINISHED_GOODS.equalsIgnoreCase(bomDataEntryForm.getProcessType()) )
                {
                    BOMDataEntryDAO.saveInventoryLotForFG( dbTransaction, bomList.iterator(), processType, vendorName );
                }*/
                if (dbTransaction != null)
                {
                    dbTransaction.commit ();
                }
                actionForward = "saveSuccess";
                if ( errors.isEmpty() )
                info.put ( "Lot = " + bomDataEntryForm.getLotNumber(),"Saved successfully" );
                success = true;
            }
            catch(Exception e)
            {
                e.printStackTrace();
                errors.put( "Error storing the BOM Lot information", null );
            }
            finally
            {
                if ( !success  && dbTransaction != null )
                {
                    try { dbTransaction.rollback (); } catch ( DBXException ignore ) {}
                }
            }
        }
        if( "refresh".equalsIgnoreCase( action ) )
        {
            request.setAttribute ( "action", "lotnumber" );
        }
        if ( action.equals ( "location" ) || action.equals ( "lotnumber" ) || action.equals ( "partnumber" ))
		{
            bomDataEntryForm.setLotNumber( null);
            bomDataEntryForm.setBomLotBinDataEntered( false);
            //bomDataEntryForm.setBomLotBinData( new ArrayList() );
        }
        if ( "".equalsIgnoreCase(action)  )
		{
			bomDataEntryForm.setProcessStepId( "0" );
			request.setAttribute( SessionKeys.INFO_MESSAGES, request.getAttribute( SessionKeys.INFO_MESSAGES ) );
			request.setAttribute( SessionKeys.ERROR_MESSAGES, request.getAttribute( SessionKeys.ERROR_MESSAGES ) );
		}
		else
		{
			request.setAttribute( SessionKeys.INFO_MESSAGES, info );
			request.setAttribute( SessionKeys.ERROR_MESSAGES, errors );
		}
        return ( mapping.findForward( actionForward ) );
    }

    private ArrayList getLotList ( String processStepId, String locationId, String processType )
	{
		java.util.ArrayList lotList = new ArrayList ();
		try
		{
			ArrayList lotNumberList = BOMDataEntryDAO.getRunningLotNumbersByPSTypeName ( processStepId, locationId, processType );
			Lot lot = null;
			lotList = new java.util.ArrayList ();

			for ( int i = 0; i < lotNumberList.size (); i++ )
			{
				lot = ( Lot ) lotNumberList.get ( i );
				lotList.add ( new org.apache.struts.util.LabelValueBean ( lot.getLotNumber (), lot.getLotId () ) );
			}
		}
		catch ( Exception e )
		{
             e.printStackTrace();
		}
		return lotList;
	}
    /**
     * This method is to check whether all the wafers in lot are scrapped or not.
     * @param bomDataEntryForm
     * @return isScrap
     */
    private boolean getBinLotScrapStatus( BOMDataEntryForm bomDataEntryForm )
    {
        ArrayList bomBinDataList = bomDataEntryForm.getBomLotBinData();
        boolean isScrap = true;
        if( bomBinDataList != null )
        {
            for( int i=0; i<bomBinDataList.size(); i++ )
            {
                 BOMLotBinData bomLotBinData = (BOMLotBinData)bomBinDataList.get(i);
                 if( bomLotBinData.isScrap() == false )
                 {
                     isScrap = false;
                 }
            }
        }
        else
        {
            isScrap = false;
        }

        return isScrap;
    }

    private ArrayList getProcessTypes()
    {
        ArrayList processTypes = new ArrayList();
        processTypes.add(new LabelValueBean(Constants.LOCATION_TYPE_DIE_BANK, Constants.LOCATION_TYPE_DIE_BANK));
        /*processTypes.add(new LabelValueBean(Constants.LOCATION_TYPE_ASSEMBLY, Constants.LOCATION_TYPE_ASSEMBLY));*/
        processTypes.add(new LabelValueBean(Constants.LOCATION_TYPE_FINISHED_GOODS, Constants.LOCATION_TYPE_FINISHED_GOODS));
        return processTypes;
    }

}
